package com.amkai.aes.webservice.binary.objecthandler.license;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import com.amkai.aes.aescommon.service.binary.job.license.BEWrapper;
import com.amkai.aes.aescommon.service.binary.job.license.EWrapper;
import com.amkai.aes.aescommon.service.binary.job.license.LWrapper;
import com.amkai.aes.aescommon.service.binary.job.license.LicenseJob;
import com.amkai.aes.aescommon.service.result.license.LicenseResult;
import com.amkai.aes.generatedbeans.organization.Department;
import com.amkai.aes.generatedbeans.organization.DepartmentType;
import com.amkai.aes.generatedbeans.scheduling.ScheduleColumn;
import com.amkai.aes.server.manager.license.AOServerLicenseHolder;
import com.amkai.aes.server.manager.license.AOServerLicenseManager;
import com.amkai.aes.server.manager.license.LicenseDataManager;
import com.amkai.common.base.licensing.schema.generated.BusinessEntityType;
import com.amkai.common.extensions.hibernate.config.manager.SessionManager;

/**
 * #18021
 * @author lkovari
 *
 */
public class AOServerLicenseHandler {
	private AOServerLicenseManager aoServerLicenseManager = null;
	private SessionManager sessionManager = null;

	/**
	 * 
	 * @param sm
	 * @throws Exception
	 */
	public AOServerLicenseHandler(SessionManager sm) throws Exception {
		this.sessionManager = sm;
		aoServerLicenseManager = new AOServerLicenseManager(sessionManager, null);
	}
	
	@Override
	protected void finalize() throws Throwable {
		aoServerLicenseManager = null;
		super.finalize();
	}
	
	public LicenseResult processJob(LicenseJob job) throws Exception {
		if (aoServerLicenseManager == null)
			aoServerLicenseManager = new AOServerLicenseManager(sessionManager, null);
		LicenseResult licenseResult = null;
		licenseResult = new LicenseResult();
		if (job.getLicenseJobKind() != null) {
			try {
				switch (job.getLicenseJobKind()) {
				case CHECK_BG_COUNT : {
					//#18265
					boolean isBGCountMatched = aoServerLicenseManager.checkBGCount(true);
					licenseResult.setBGCountMatched(isBGCountMatched);
					break;
				}
				case CHECK_ENTERPRISE_NAME : {
					boolean isEnterpriseNameMatched = aoServerLicenseManager.checkEnterpriseName();
					licenseResult.setEnterpriseNameMatched(isEnterpriseNameMatched);
					break;
				}
				case CHECK_DBID : {
					boolean isDBIdMatched = aoServerLicenseManager.checkDBId();
					licenseResult.setDBIdMatched(isDBIdMatched);
					break;
				}
				case CHECk_AOCODE : {
					//#18265
					boolean isAOCodeVersionMatched = aoServerLicenseManager.checkAOCodeVersion(true);
					licenseResult.setAOCodeVersionMatched(isAOCodeVersionMatched);
					break;
				}
				case IS_LICENSE_EXPIRED : {
					boolean isLicenseExpired = aoServerLicenseManager.isLicesneExpired(false);
					licenseResult.setLicenseExpired(isLicenseExpired);
					break;
				}
				case IS_MODULE_LICENSED: {
					boolean isModuleLicensed = false;
					switch (job.getLicenseModuleKind()) {
					case BILLING : {
						isModuleLicensed = aoServerLicenseManager.checkBilling(job.getBeKey());
						break;
					}
					//#18430
					case IOS : {
						isModuleLicensed = aoServerLicenseManager.checkIOS(job.getBeKey());
						break;
					}
					case EPO : {
						isModuleLicensed = aoServerLicenseManager.checkEPO(job.getBeKey());
						break;
					}
					case ERP : {
						isModuleLicensed = aoServerLicenseManager.checkEPO(job.getBeKey());
						break;
					}
					case EVER : {
						isModuleLicensed = aoServerLicenseManager.checkEVER(job.getBeKey());
						break;
					}
					case HR : {
						isModuleLicensed = aoServerLicenseManager.checkHR(job.getBeKey());
						break;
					}
					case IMM : {
						isModuleLicensed = aoServerLicenseManager.checkIMM(job.getBeKey());
						break;
					}
					case RCM : {
						isModuleLicensed = aoServerLicenseManager.checkRCM(job.getBeKey());
						break;
					}
					}
					licenseResult.setModuleLicensed(isModuleLicensed);
				}
				case IS_LICENSE_INSTALLED: {
					//#18021-09/04/11
					licenseResult.setLicenseInstalled(aoServerLicenseManager.isLicenseInstalled(false));
					break;		
				}
				case IS_LICENSE_ALLOWED_FOR_BE : {
					boolean isLicensedBE = aoServerLicenseManager.isBusinessEntityLicensed(job.getBeKey());
					licenseResult.setBusinessEntityLicensed(isLicensedBE);
					break;
				}
				case IS_ALLOW_TO_ADD_BUSINESSENTITY : {
					//#18265
					boolean isAllowToAddBE = aoServerLicenseManager.isAllowToAddBusinessEntity(true);
					licenseResult.setAllowedToAddBusinessEntity(isAllowToAddBE);
					break;
				}
				case IS_ALLOW_TO_ADD_BUSINESGROUP : {
					//#18265
					boolean isAllowToAddBG = aoServerLicenseManager.isAllowToAddBusinessGroup(true);
					licenseResult.setAllowedToAddBusinessGroup(isAllowToAddBG);
					break;
				}
				case IS_OR_AND_PROC_ROOMS_LICENSED : {
					//#18265
					boolean isORAndProcRoomLicensed = aoServerLicenseManager.isORAndProcRoomLicensed(job.getBeKey(), true);
					licenseResult.setORAndProcRoomsLicensed(isORAndProcRoomLicensed);
					break;
				}
				case ALLOWED_ORROOM : {
					licenseResult.setAllowedORRooms(aoServerLicenseManager.allowedORRooms(job.getBeKey()));
					break;
				}
				case ALLOWED_PROCROOM : {
					licenseResult.setAllowedProcRooms(aoServerLicenseManager.allowedPROCRooms(job.getBeKey()));
					break;
				}
				case IS_ALLOW_TO_ADD_ORROOM : {
					boolean isAllowToAddORRoom = aoServerLicenseManager.isAllowToAddORRoom(job.getBeKey(), job.getId(), true);
					licenseResult.setAllowToAddORRoom(isAllowToAddORRoom);
					break;
				}
				case IS_ALLOW_TO_ADD_PROCROOM : {
					boolean isAllowToAddProcRoom = aoServerLicenseManager.isAllowToAddPROCRoom(job.getBeKey(), job.getId(), true);
					licenseResult.setAllowToAddProcRoom(isAllowToAddProcRoom);
					break;
				}
				case IS_BUSINESSENTITY_DISABLED : {
					boolean isBusinessEntityDisabled = aoServerLicenseManager.isBusinessEntityDisabled(job.getBeKey(), job.getId());
					licenseResult.setBusinessEntityDisabled(isBusinessEntityDisabled);
					break;
				}
				case UPDATE_KEY_OF_BUSINESSENTITY : {
					try {
						boolean isSuccess = aoServerLicenseManager.updateBusinessEntityLicenseKey(job.getBeWrapper(), job.getId());
						licenseResult.setUpdateBEKeySuccess(isSuccess);
					}
					catch (Exception e) {
						licenseResult.setException(e);
						licenseResult.setUpdateBEKeySuccess(false);
					}
					break;
				}
				case DOWNLOAD_UNUSED_BE_LICENSES : {
					Collection<BusinessEntityType> unusedBusinessEntityLicenses = aoServerLicenseManager.loadUnusedBusinessEntityLicenses();
					List<Object> beWrappers = new ArrayList<Object>();
					for (BusinessEntityType bet : unusedBusinessEntityLicenses) {
						BEWrapper beWrapper = new BEWrapper();
						beWrapper.captureBusinessEntityTypeData(bet, null);
						beWrappers.add(beWrapper);
					}
					licenseResult.setBusinesEntityLicenses(beWrappers);
					break;
				}
				case DOWNLOAD_LICENSE : {
					EWrapper eWrapper = new EWrapper();
					eWrapper.captureEnterpriseData(AOServerLicenseHolder.license.getEnterprise());
					LWrapper licenseWrapper = new LWrapper(eWrapper);
					for (BusinessEntityType bet: AOServerLicenseHolder.license.getBusinessEntity()) {
						BEWrapper  beWrapper = new BEWrapper();
						Department dep = AOServerLicenseHolder.usedDepartmentsMap.get(bet.getKey());
						// is licensed/used/
						if (dep != null) {
							DepartmentType depType = aoServerLicenseManager.downloadDepartmentType(dep);
							dep.setDepartmentType(depType);
							beWrapper.captureBusinessEntityTypeData(bet, dep);
						}
						else {
							beWrapper.captureBusinessEntityTypeData(bet, null);
						}
						licenseWrapper.getBusinessEntityWrappers().add(beWrapper);
					}
					Collections.sort(licenseWrapper.getBusinessEntityWrappers(), new Comparator<BEWrapper>() {
						@Override
						public int compare(BEWrapper bew1, BEWrapper bew2) {
							int res = 0;
							res = bew2.getName().compareToIgnoreCase(bew1.getName());
							if (res == 0) {
								res = bew1.getTypeBEString().compareToIgnoreCase(bew2.getTypeBEString());
							}
							return res;
						}
						
					});
					licenseResult.setLicenseWrapper(licenseWrapper);
					break;
				}
				case DOWNLOAD_DISABLED_BUSINESSENTIES : {
					List<BEWrapper> beWrappers = new ArrayList<BEWrapper>();
					for (Department dep : AOServerLicenseHolder.disabledBusinessEntitiesMap.values()) {
						BEWrapper bew = new BEWrapper();
						int numOfOR = aoServerLicenseManager.orRoomsInUse(dep.getId());
						int numOfProc = aoServerLicenseManager.procRoomsInUse(dep.getId());
//FIXME need to set detailed data						
						int numOfHL7In = 0;
						int numOfHL7Out = 0;
						DepartmentType depType = aoServerLicenseManager.downloadDepartmentType(dep);
						dep.setDepartmentType(depType);
						bew.captureBusinessEntityData(dep, numOfOR, numOfProc, numOfHL7In, numOfHL7Out);
						beWrappers.add(bew);
					}
					licenseResult.setDisabledBusinessEntities(beWrappers);
					break;
				}
				//#18454
				case DOWNLOAD_USED_BE : {
					Collection<Object> objectList = aoServerLicenseManager.downloadLicensedBusinessEntities();
					licenseResult.setBusinesEntityLicenses(new ArrayList<Object>(objectList));
					break;
				}
				case DOWNLOAD_SCHEDULECOLUMNS : {
					try {
						List<Object> objectList = aoServerLicenseManager.downloadScheduleColumns(job.getIdList());
						List<ScheduleColumn> scheduleColumns = new ArrayList<ScheduleColumn>();
						for (Object o : objectList) {
							if (o instanceof ScheduleColumn) {
								ScheduleColumn sc = (ScheduleColumn)o;
								scheduleColumns.add(sc);
							}
						}
						licenseResult.setScheduleColumns(scheduleColumns);
					}
					catch (Exception e) {
						licenseResult.setException(e);
					}
					break;
				}
				}
			}
			catch (Exception e) {
				licenseResult.setException(e);
			}
		}
		return licenseResult;
	}
	
}
